#include <cautemutmtcserver/CAUTEmuTMTCServerE.h>

// ***********************************************************************

// class EDROOMTopContext

// ***********************************************************************



	// CONSTRUCTORES***********************************************

CAUTEmuTMTCServer::EDROOMTopContext::EDROOMTopContext (CAUTEmuTMTCServer &act, CDDataBurst & EDROOMpVarVDataBurst, CPackListHandler & EDROOMpVarVFreePackList, int & EDROOMpVarVnumMensajeTC, int & EDROOMpVarVnumMensajeTM, PackPool & EDROOMpVarVPackListPool, CPackListHandler & EDROOMpVarVRouterFree, CPackListHandler & EDROOMpVarVRouterTC, CPackListHandler & EDROOMpVarVTCPackList, CPackListHandler & EDROOMpVarVTMPackList, CEDROOMPOOLCDTMTCCommServer & EDROOMpPoolCDTMTCCommServer ):

	EDROOMcomponent(act)
	,Msg(EDROOMcomponent.Msg)
	,MsgBack(EDROOMcomponent.MsgBack)
	,SgiTMTCServer2(EDROOMcomponent.SgiTMTCServer2)
	,SgiTMTCServer(EDROOMcomponent.SgiTMTCServer)
	, VDataBurst ( EDROOMpVarVDataBurst )
	, VFreePackList ( EDROOMpVarVFreePackList )
	, VnumMensajeTC ( EDROOMpVarVnumMensajeTC )
	, VnumMensajeTM ( EDROOMpVarVnumMensajeTM )
	, VPackListPool ( EDROOMpVarVPackListPool )
	, VRouterFree ( EDROOMpVarVRouterFree )
	, VRouterTC ( EDROOMpVarVRouterTC )
	, VTCPackList ( EDROOMpVarVTCPackList )
	, VTMPackList ( EDROOMpVarVTMPackList )
	, CEDROOMPoolCDTMTCCommServer ( EDROOMpPoolCDTMTCCommServer )
 {

}

CAUTEmuTMTCServer::EDROOMTopContext::EDROOMTopContext ( EDROOMTopContext &contex ):

	EDROOMcomponent(contex.EDROOMcomponent),
	Msg(contex.Msg),
	MsgBack(contex.MsgBack)
	,SgiTMTCServer2(contex.SgiTMTCServer2)
	,SgiTMTCServer(contex.SgiTMTCServer)
	, VDataBurst ( contex.VDataBurst )
	, VFreePackList ( contex.VFreePackList )
	, VnumMensajeTC ( contex.VnumMensajeTC )
	, VnumMensajeTM ( contex.VnumMensajeTM )
	, VPackListPool ( contex.VPackListPool )
	, VRouterFree ( contex.VRouterFree )
	, VRouterTC ( contex.VRouterTC )
	, VTCPackList ( contex.VTCPackList )
	, VTMPackList ( contex.VTMPackList )
	, CEDROOMPoolCDTMTCCommServer ( contex.CEDROOMPoolCDTMTCCommServer )
 {

}

	// EDROOMSearchContextTrans********************************************

bool CAUTEmuTMTCServer::EDROOMTopContext::EDROOMSearchContextTrans(TEDROOMTransId &edroomCurrentTrans){

	bool edroomValidMsg=false; 

	 switch(Msg->signal){

		 case ( EDROOMSignalDestroy ): 

			 edroomValidMsg=true;
			 edroomCurrentTrans.distanceToContext = 0 ;
			 edroomCurrentTrans.localId = -1 ;
			 break;

	}

	return(edroomValidMsg);

}

	// Funciones Definidas por el usuario  ****************************

bool_t	CAUTEmuTMTCServer::EDROOMTopContext::FGetTMPackets(int32_t numeroFichero,byte_t *mensaje)

{ 	
	FILE *fichero;
	char ruta[50];
	byte_t aux[10];
 
#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_MULTI_TM
   strcpy(ruta,"MultiTM/");
#endif
#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_ONE_TM
   strcpy(ruta,"OneTM/");
#endif
	FIntToChar(numeroFichero,aux);
	strcat(ruta,(char *)aux);
	fichero=fopen(ruta,"rb");    
	if (fichero==NULL)
	{
	   return false;
	}
	else
	{
		fread(mensaje,1,254,fichero);
		fclose(fichero);
	}

	return true;
}


bool_t	CAUTEmuTMTCServer::EDROOMTopContext::FGetTCPackets(int32_t numeroFichero,byte_t *mensaje)

{
   FILE *fichero;
   char ruta[50];
   byte_t aux[10];


#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_MULTI_TC
   strcpy(ruta,"MultiTC/");
#endif
#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_ONE_TC
   strcpy(ruta,"OneTC/");
#endif

   FIntToChar(numeroFichero,aux);
   strcat(ruta,(char *)aux);

   fichero=fopen(ruta,"rb");
   if (fichero==NULL)
   {
   	return false;
   }
   else
   {
		fread(mensaje,1,254,fichero);
		fclose(fichero);
 	}

  return true;
}



void	CAUTEmuTMTCServer::EDROOMTopContext::FInit()

{
	init_CRC_word16_table();
	FInitFreePackPool();
	FSendInitRouter();
}



void	CAUTEmuTMTCServer::EDROOMTopContext::FInitFreePackPool()

{
	//Inicializamos el Pool para los paquetes
	word16_t numPackagesTM;
	word16_t numPackagesTC;
	word16_t numFreeList;
#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_MULTI_TC
    numPackagesTC=125;
#endif
#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_MULTI_TM
    numPackagesTM=95;
#endif
#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_ONE_TC
    numPackagesTC=13;
#endif
#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_ONE_TM
	numPackagesTM=12;
#endif
    numFreeList=32;
	VPackListPool.InitPackagesMemory();
	VPackListPool.AllocPackages(numPackagesTM,VTMPackList);
	VPackListPool.AllocPackages(numPackagesTC,VTCPackList);
 	VPackListPool.AllocPackages(numFreeList,VFreePackList);
    VPackListPool.AllocPackages(numFreeList,VRouterFree);
	VPackListPool.AllocPackages(numPackagesTC,VRouterTC);//para el router
 
	FInitTMFiles();
 	FInitTCFiles();

	
}



void CAUTEmuTMTCServer::EDROOMTopContext::FInitTMFiles()

{
	byte_t newPack[254];
	int32_t num = 1;
	bool_t continuar;


	//Inicializar TM con los ficheros
	VTMPackList.ToHeadPack();
	if ( VTMPackList.GetPackCounter() )
	{
		do
		{
			CPackHandler newPackHandler;
			VTMPackList.GetCurrentEditPack(newPackHandler);
			continuar = FGetTMPackets(num, newPack);
			for (int32_t i = 0; i<254; i++)
			{
				newPackHandler.WriteByte(i, newPack[i]);
			}
			VTMPackList.WriteCRCCurrentEditPack(0, 254);
			num++;
		}
		while (continuar&&VTMPackList.NextEditPack());
	}

}



void CAUTEmuTMTCServer::EDROOMTopContext::FIntToChar(int32_t num, byte_t * cConvert)

{

	byte_t aux;
	int32_t i = 0;
	int32_t j = 0;
	
	do
	{
		cConvert[i++] = (num%10)+'0';
		num = num/10;
	}
	while (num>0);
	cConvert[i--] = '\0';
	for (j = 0; i>j; i--, j++)
	{
		aux = cConvert[i];
		cConvert[i] = cConvert[j];
		cConvert[j] = aux;
	}
}



void	CAUTEmuTMTCServer::EDROOMTopContext::FReady()

{
// 	printf("TMTC Server: FReady\n");
//	printf("TMTC Server: FReady --> VTMPackList: %d\n",VTMPackList.GetPackCounter());
//	printf("TMTC Server: FReady --> VTCPackList: %d\n",VTCPackList.GetPackCounter());
//	printf("TMTC Server: FReady --> VFreePackList: %d\n",VFreePackList.GetPackCounter());
//	printf("TMTC Server: FReady --> VRouterFree: %d\n",VRouterFree.GetPackCounter());
//	printf("TMTC Server: FReady --> VRouterTC: %d\n",VRouterTC.GetPackCounter());
}



void	CAUTEmuTMTCServer::EDROOMTopContext::FSendInitRouter()

{
 	CDTMTCCommServer * ap_CDTMTCCommServer = CEDROOMPoolCDTMTCCommServer.AllocData();
	
		// Complete Data 
	
	ap_CDTMTCCommServer->packList1=VRouterTC;
	ap_CDTMTCCommServer->packList2=VRouterFree;
 
		// send new Msg
	
	SgiTMTCServer2.send(EmuGSDoublePackList, EDROOMprioNormal, ap_CDTMTCCommServer, &CEDROOMPoolCDTMTCCommServer);
 
}



void	CAUTEmuTMTCServer::EDROOMTopContext::FSendTCPackList()

{
 
	CDTMTCCommServer * ap_CDTMTCCommServer = CEDROOMPoolCDTMTCCommServer.AllocData();
	
		// Complete Data 
	ap_CDTMTCCommServer->packList1=VTCPackList;
	//ap_CDTMTCCommServer->packList2=VTCPackList;//TODO: La segunda es redundante
 
		// reply 
	
	Msg->reply(STMTCPackList, ap_CDTMTCCommServer, &CEDROOMPoolCDTMTCCommServer);

 
}




void	CAUTEmuTMTCServer::EDROOMTopContext::FSendTMPackets()

{
	word16_t nPacksNum;
	if (VnumMensajeTM!=0) //TEMPORAL
	{
		CDTMTCCommServer & varCDTMTCCommServer = *(CDTMTCCommServer *)Msg->data;
		nPacksNum=varCDTMTCCommServer.packList2.GetPackCounter();
		varCDTMTCCommServer.packList2.ExtractPackages(nPacksNum,VFreePackList);
		VTMPackList=varCDTMTCCommServer.packList1;
	}
	CDTMTCCommServer * ap_CDTMTCCommServer = CEDROOMPoolCDTMTCCommServer.AllocData();
	
		// Complete Data 

	ap_CDTMTCCommServer->packList1=VTMPackList;
	ap_CDTMTCCommServer->packList2=VFreePackList;

		// reply 
	
	Msg->reply(STMTCPackList, ap_CDTMTCCommServer, &CEDROOMPoolCDTMTCCommServer);

 	VnumMensajeTM++;//TEMPORAL
 
}



void	CAUTEmuTMTCServer::EDROOMTopContext::FStoreTCFiles()

{

	CPackHandler newPackHandler;
	byte_t dataBurst[256];

	VTCPackList.ToHeadPack();
	if(VTCPackList.GetPackCounter())
	{
		do
		{
 
			VTCPackList.GetCurrentReadPack(newPackHandler);
			for (int32_t i=0; i<256;i++)
			{
				newPackHandler.ReadByte(i,dataBurst[i]);
			}
			FStoreTCFrame(dataBurst);//TODO:TEMPORAL

		}
		while (VTCPackList.NextReadPack());
	}
 
 
 
}



void	CAUTEmuTMTCServer::EDROOMTopContext::FStoreTCFrame(byte_t * frames)

{
	char ruta[50];
	byte_t aux[10];
 	FILE *fichero;
#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_MULTI_TC
 	strcpy(ruta,"EndMultiTC/");
#endif
#ifdef CONFIG_CAEMUPLANNER_SWR_TEST_ONE_TC
 	strcpy(ruta,"EndOneTC/");
#endif
	FIntToChar(frames[0],aux);
	strcat(ruta,(char *)aux);
 	fichero=fopen(ruta,"ab");
	if (fichero!=NULL)
    {
		fwrite(frames+2,1,(frames[2]+2), fichero);
		fclose(fichero);
	}
 
 
}



void	CAUTEmuTMTCServer::EDROOMTopContext::FStoreTCPackets()

{

	CDTMTCCommServer & varCDTMTCCommServer = *(CDTMTCCommServer *)Msg->data;
 
	VTCPackList=varCDTMTCCommServer.packList1;
	VTCPackList=varCDTMTCCommServer.packList2;

	FStoreTCFiles();

	CDTMTCCommServer * ap_CDTMTCCommServer = CEDROOMPoolCDTMTCCommServer.AllocData();
	// Complete Data 
	ap_CDTMTCCommServer->packList1=VTCPackList;
	ap_CDTMTCCommServer->packList2=VTCPackList;
	
	// reply 
	Msg->reply(STMTCPackList, ap_CDTMTCCommServer, &CEDROOMPoolCDTMTCCommServer);

//	printf("----------------------------------------------------------------------\n");
//	printf("TMTC Server: FReady --> VTMPackList: %d\n",VTMPackList.GetPackCounter());
//	printf("TMTC Server: FReady --> VTCPackList: %d\n",VTCPackList.GetPackCounter());
//	printf("TMTC Server: FReady --> VFreePackList: %d\n",VFreePackList.GetPackCounter());
//
}
 



void	CAUTEmuTMTCServer::EDROOMTopContext::FInitTCFiles()

{
 	bool_t continuar;
	int32_t num=1;
	byte_t newPack[254];
 
	//Inicializar TC con los ficheros
	VRouterTC.ToHeadPack();
	if(VRouterTC.GetPackCounter())
	{
		do
		{
			CPackHandler newPackHandler;
			VRouterTC.GetCurrentEditPack(newPackHandler);
			continuar=FGetTCPackets (num,newPack);
			for (int32_t i=0;i<254;i++)
			{
				newPackHandler.WriteByte(i,newPack[i]);
			}
			VRouterTC.WriteCRCCurrentEditPack(0,254);
 
			num++;
		}
		while (continuar && VRouterTC.NextEditPack());
	}
 
 
}
 






	//*****Pools

	//CEDROOMPOOLCDTMTCCommServer

CAUTEmuTMTCServer::EDROOMTopContext::CEDROOMPOOLCDTMTCCommServer::CEDROOMPOOLCDTMTCCommServer(unsigned int elemCount, CDTMTCCommServer* pMem, TEDROOMBool * pMemMarks):CEDROOMProtectedMemoryPool(elemCount, pMem, pMemMarks, sizeof (CDTMTCCommServer)){;}

CDTMTCCommServer *	CAUTEmuTMTCServer::EDROOMTopContext::CEDROOMPOOLCDTMTCCommServer::AllocData(){
	return(CDTMTCCommServer*)CEDROOMProtectedMemoryPool::AllocData();
}



// ***********************************************************************

// class EDROOMTopState

// ***********************************************************************



	// CONSTRUCTOR*************************************************

CAUTEmuTMTCServer::EDROOMTopState::EDROOMTopState (CAUTEmuTMTCServer &act, CEDROOMMemory *pEDROOMMemory  ):
	  EDROOMTopContext( act , VDataBurst, VFreePackList, VnumMensajeTC, VnumMensajeTM, VPackListPool, VRouterFree, VRouterTC, VTCPackList, VTMPackList,CEDROOMPoolCDTMTCCommServer )
	, VDataBurst (   )
	, VFreePackList (   )
	, VnumMensajeTC ( 0 )
	, VnumMensajeTM ( 0 )
	, VPackListPool (   )
	, VRouterFree (   )
	, VRouterTC (   )
	, VTCPackList (   )
	, VTMPackList (   )
	, CEDROOMPoolCDTMTCCommServer ( 3, pEDROOMMemory->poolCDTMTCCommServer, pEDROOMMemory->poolMarkCDTMTCCommServer)
{

}

	// EDROOMBehaviour**********************************************

void CAUTEmuTMTCServer::EDROOMTopState::EDROOMBehaviour(){

	TEDROOMTransId edroomCurrentTrans;

	edroomCurrentTrans = EDROOMIllegada();

	do{

		switch(edroomCurrentTrans.localId){

			case(SendTMPacks):
				FSendTMPackets();
				edroomNextState = Ready;
				break;
			case(Init):
				FInit();
				edroomNextState = Ready;
				break;
			case(ReceiveTCPacks):
				FStoreTCPackets();
				edroomNextState = Ready;
				break;
			case(SendTCPackList):
				FSendTCPackList();
				edroomNextState = Ready;
				break;
		}

		EDROOMcomponent.EDROOMTraceStateEntry();

		EDROOMcomponent.EDROOMTraceStateEntry();

		switch(edroomNextState){

			case(I):
				edroomCurrentTrans=EDROOMIllegada();
				break;

			case(Ready):
				FReady();
				edroomCurrentTrans=EDROOMReadyllegada();
				break;

		}

		EDROOMcomponent.EDROOMTraceStateExit();

		edroomCurrentState=edroomNextState;

	}while(Msg->signal != EDROOMSignalDestroy);

}



	// Inicio**********************************************

void CAUTEmuTMTCServer::EDROOMTopState::EDROOMInicio(){

edroomCurrentState=I;

}



//	 ***********************************************************************

//	 llegada SubEstado I

//	 ***********************************************************************



TEDROOMTransId CAUTEmuTMTCServer::EDROOMTopState::EDROOMIllegada(){

	TEDROOMTransId edroomCurrentTrans;

	edroomCurrentTrans.localId = Init;
	edroomCurrentTrans.distanceToContext = 0;
	EDROOMcomponent.EDROOMTraceTrans(edroomCurrentTrans, 0);

	return(edroomCurrentTrans);

}



	// ***********************************************************************

	// llegada SubEstado Hoja Ready

	// ***********************************************************************



TEDROOMTransId CAUTEmuTMTCServer::EDROOMTopState::EDROOMReadyllegada(){

	TEDROOMTransId edroomCurrentTrans;

	int edroomValidMsg=false;

	do{

		EDROOMNuevoMens ();

		switch(Msg->signal){

			case (STMDoublePackList): 

				 if ( *Msg->GetPInterface() == SgiTMTCServer) {

					edroomCurrentTrans.localId= SendTMPacks;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

			case (SFinalTCPackets): 

				 if ( *Msg->GetPInterface() == SgiTMTCServer) {

					edroomCurrentTrans.localId= ReceiveTCPacks;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

			case (STCPackList): 

				 if ( *Msg->GetPInterface() == SgiTMTCServer) {

					edroomCurrentTrans.localId= SendTCPackList;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

		};

		if (!edroomValidMsg) edroomValidMsg = EDROOMSearchContextTrans(edroomCurrentTrans);

	} while (!edroomValidMsg);

	EDROOMcomponent.EDROOMTraceTrans(edroomCurrentTrans, Msg->signal);

	return(edroomCurrentTrans);

}



